namespace TwitterButtler.RequestServer.WakeOnLan
{
	#region #using Directives

	using System;
	using System.ComponentModel.Composition;
	using System.Linq;
	using System.Net.NetworkInformation;

	using Infrastructure;

	#endregion

	[Export(typeof(IButtlerRequestServer))]
	public class WhoIsOnlineButtlerRequestServer : MachinePowerStatusButtlerRequestServerBase,
	                                               IButtlerRequestServer
	{
		#region IButtlerRequestServer Members

		public bool CanPerformRequest(string userName, string requestText)
		{
			requestText = requestText.Trim();

			return requestText.StartsWith("who's online", StringComparison.InvariantCultureIgnoreCase) ||
			       requestText.StartsWith("who is online", StringComparison.InvariantCultureIgnoreCase);
		}

		public void PerformRequest(DateTime originalRequestDateTime, string requestText, string screenName, Action<string, string> onRequestCompleted)
		{
			var entries = this.userNameToMacAddressDictionary.Values.Where(x => !string.IsNullOrEmpty(x.MachineName));
			var onlineUsers = entries.AsParallel().Where(UsersAreOnline).Select(x => x.UserName).ToArray();

			onRequestCompleted(screenName,
			                   onlineUsers.Any()
			                   	? string.Format("The following users have their machines online: {0}.", string.Join(", ", onlineUsers.OrderBy(a => a)))
			                   	: "No machines are online.");
		}

		#endregion

		private static bool UsersAreOnline(WakeOnLanUserEntry entry)
		{
			try
			{
				return Ping(entry, 1);
			}
			catch (PingException)
			{
				return false;
			}
		}
	}
}